package com.chinatechstar.file.controller;

import java.io.IOException;
import java.util.*;

import javax.servlet.http.HttpServletResponse;

import com.chinatechstar.file.dto.CurrDirFileDTO;
import com.chinatechstar.file.dto.CurrDirFileMapDTO;
import com.chinatechstar.file.dto.SysDirTreeDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.chinatechstar.file.entity.SysFile;
import com.chinatechstar.file.service.SysFileService;
import com.chinatechstar.component.commons.result.ActionResult;
import com.chinatechstar.component.commons.result.ListResult;
import com.chinatechstar.component.commons.result.ResultBuilder;
import com.chinatechstar.component.commons.utils.ExcelUtils;
import com.chinatechstar.component.commons.validator.InsertValidator;
import com.chinatechstar.component.commons.validator.UpdateValidator;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件管理 的控制层
 */
@Api(value = "文件管理 的控制层", tags = {"文件管理"})
@RestController
@RequestMapping("/sysfile")
public class SysFileController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private SysFileService sysFileService;

    /**
     * 查询 文件管理 所有数据
     *
     * @return ListResult<Object>
     */
    @ApiOperation(value = "查询 文件管理 所有数据", tags = {"文件管理"})
    @GetMapping(path = "/findSysFileAll")
    public ListResult<Object> findSysFileAll() {
        List<SysFile> list = sysFileService.findSysFileAll();
        return ResultBuilder.buildListSuccess(list);
    }

    /**
     * 查询 文件管理 分页
     *
     * @param currentPage 当前页数
     * @param pageSize    每页记录数
     * @param name        名称
     * @param sorter      排序
     * @return ListResult<Object>
     */
    @ApiOperation(value = "查询 文件管理 分页", tags = {"文件管理"})
    @GetMapping(path = "/findSysFileByCondition")
    public ListResult<Object> findSysFileByCondition(@RequestParam(name = "currentPage", required = false, defaultValue = "1") Integer currentPage,
                                                     @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                                                     @RequestParam(name = "name", required = false) String name,
                                                     @RequestParam(name = "sorter", required = false) String sorter) {
        Map<String, Object> data = sysFileService.findSysFileByCondition(currentPage, pageSize, name, sorter);
        return ResultBuilder.buildListSuccess(data);
    }

    /**
     * 根据查询条件导出 文件管理
     *
     * @param response 响应对象
     * @param paramMap 参数Map
     */
    @ApiOperation(value = "根据查询条件导出 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/exportSysFile")
    public void exportSysFile(HttpServletResponse response, @RequestParam Map<String, Object> paramMap) {
        try {
            List<String> headList = Arrays.asList("ID", "名称", "创建时间");
            List<LinkedHashMap<String, Object>> dataList = sysFileService.findSysFileForExcel(paramMap);
            ExcelUtils.exportExcel(headList, dataList, "管理", response);
        } catch (Exception e) {
            logger.warn(e.toString());
        }
    }

    /**
     * 根据主键ID查询 文件管理 数据
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数据查询 文件管理 数据", tags = {"文件管理"})
    @GetMapping(path = "/findSysFileById")
    public ActionResult findSysFileById(@RequestParam(name = "id") Long id) {
        SysFile data = sysFileService.findSysFileById(id);
        return ResultBuilder.buildActionSuccess(data);
    }

    /**
     * 根据主键ID数组查询 文件管理 数据
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组查询 文件管理 数据", tags = {"文件管理"})
    @GetMapping(path = "/findSysFileByIds")
    public ListResult<Object> findSysFileByIds(@RequestParam(name = "ids") Long[] ids) {
        List<SysFile> list = sysFileService.findSysFileByIds(ids);
        return ResultBuilder.buildListSuccess(list);
    }

    /**
     * 新增 文件管理
     *
     * @param sysFile 文件管理 实体
     * @return ActionResult
     */
    @ApiOperation(value = "新增 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/addSysFile")
    public ActionResult addSysFile(@Validated(InsertValidator.class) @RequestBody SysFile sysFile) {
        sysFileService.insertSysFile(sysFile);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 批量新增 文件管理
     *
     * @param sysFiles 文件管理 实体数组
     * @return ActionResult
     */
    @ApiOperation(value = "批量新增 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/addSysFiles")
    public ActionResult addSysFiles(@Validated(InsertValidator.class) @RequestBody List<SysFile> sysFiles) {
        sysFileService.insertSysFiles(sysFiles);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 复制或移动目录和文件命令
     *
     * @param command      操作命令 copy | move
     * @param fileIds      需要复制或移动的目录和文件id数组
     * @param targetId     目录id
     * @param fileBusiness 业务id
     */
    @ApiOperation(value = "复制或移动目录和文件命令 command: copy | move", tags = {"文件信息"})
    @PostMapping(value = "/copyMoveCommand", consumes = {"multipart/form-data"})
    public ActionResult copyMoveCommand(@RequestParam(name = "command") String command,
                                        @RequestParam(name = "fileIds") Long[] fileIds,
                                        @RequestParam(name = "targetId") Long targetId,
                                        @RequestParam(name = "fileBusiness") Long fileBusiness) {
        HashMap<String, HashMap<String, String>> info = sysFileService.copyMoveCommand(command, fileIds, targetId, fileBusiness);
        return ResultBuilder.buildActionSuccess(info);
    }


    /**
     * 文件或目录下载
     *
     * @param fileId   文件目录id
     * @param command  file | dir
     * @param response Http响应消息
     */
    @ApiOperation(value = "文件或目录下载 command: file | dir", tags = {"文件信息"})
    @GetMapping(value = "/downloadCommand")
    public void downloadCommand(@RequestParam(name = "id") Long fileId,
                                @RequestParam(name = "command") String command,
                                HttpServletResponse response) {
        try {
            sysFileService.downloadCommand(fileId, command, response);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }




    /**
     * 目录操作
     *
     * @param command       操作命令 mkdir | rename
     * @param dirName       目录名称
     * @param fileBusiness  业务id
     * @param fileStorageId 文件仓储id
     * @param targetId      目标id
     * @return ActionResult
     */
    @ApiOperation(value = "目录操作 command: mkdir | rename", tags = {"文件信息"})
    @PostMapping(value = "/dirCommand", consumes = {"multipart/form-data"})
    public ActionResult dirCommand(@RequestParam(name = "command") String command,
                                   @RequestParam(name = "dirName", required = false) String dirName,
                                   @RequestParam(name = "fileBusiness") Long fileBusiness,
                                   @RequestParam(name = "fileStorageId") Long fileStorageId,
                                   @RequestParam(name = "targetId", required = false) Long targetId) throws IOException {
        HashMap<String, String> info = sysFileService.dirCommand(command, dirName, fileBusiness, fileStorageId, targetId);
        return ResultBuilder.buildActionSuccess(info);
    }

    /**
     * 打开目录
     *
     * @param businessId 业务id
     * @param targetId   目标目录id
     * @param isReview   是否查询需要的审核文件
     * @return ActionResult
     */
    @ApiOperation(value = "打开目录", tags = {"文件管理"})
    @GetMapping(path = "/openDir")
    public ActionResult openDir(@RequestParam(name = "businessId") Long businessId,
                                @RequestParam(name = "targetId", required = false) Long targetId,
                                @RequestParam(name = "isReview", required = false) boolean isReview) {
        CurrDirFileMapDTO list = sysFileService.openDir(businessId, targetId, isReview);
        return ResultBuilder.buildActionSuccess(list);
    }

    /**
     * 搜索业务关联的文件
     *
     * @param businessId 业务id
     * @param fileName   文件名称
     * @param isReview   是否查询需要的审核文件
     * @return ActionResult
     */
    @ApiOperation(value = "搜索业务关联的文件", tags = {"文件管理"})
    @GetMapping(path = "/searchFile")
    public ActionResult searchFile(@RequestParam(name = "businessId") Long businessId,
                                   @RequestParam(name = "fileName", required = false) String fileName,
                                   @RequestParam(name = "isReview", required = false) boolean isReview) {
        CurrDirFileMapDTO list = sysFileService.searchFile(businessId, fileName, isReview);
        return ResultBuilder.buildActionSuccess(list);
    }

    /**
     * 查询业务的树状结构目录
     *
     * @param businessId 业务id
     * @return ActionResult
     */
    @ApiOperation(value = "查询业务的树状结构目录", tags = {"文件管理"})
    @GetMapping(path = "/findDirTree")
    public ActionResult findDirTree(@RequestParam(name = "businessId") Long businessId) {
        SysDirTreeDTO list = sysFileService.findDirTree(businessId);
        return ResultBuilder.buildActionSuccess(list);
    }

    /**
     * 编辑 文件管理
     *
     * @param sysFile 文件管理 实体
     * @return ActionResult
     */
    @ApiOperation(value = "编辑 文件管理", tags = {"文件管理"})
    @PutMapping(path = "/updateSysFile")
    public ActionResult updateSysFile(@Validated(UpdateValidator.class) @RequestBody SysFile sysFile) {
        sysFileService.updateSysFile(sysFile);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 批量编辑 文件管理
     *
     * @param sysFiles 文件管理 实体数组
     * @return ActionResult
     */
    @ApiOperation(value = "批量编辑 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/updateSysFiles")
    public ActionResult updateSysFiles(@Validated(UpdateValidator.class) @RequestBody List<SysFile> sysFiles) {
        sysFileService.updateSysFiles(sysFiles);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 删除 文件管理
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID删除 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/deleteSysFileById")
    public ActionResult deleteSysFileById(@RequestParam(name = "id") Long id) {
        sysFileService.deleteSysFileById(id);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 删除 文件管理
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组批量删除 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/deleteSysFileByIds")
    public ActionResult deleteSysFileByIds(@RequestParam(name = "id") Long[] ids) {
        sysFileService.deleteSysFileByIds(ids);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 软删除 文件管理
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID软删除 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/softDeleteSysFileById")
    public ActionResult softDeleteSysFileById(@RequestParam(name = "id") Long id) {
        sysFileService.softDeleteSysFileById(id);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 软删除 文件管理
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组批量软删除 文件管理", tags = {"文件管理"})
    @PostMapping(path = "/softDeleteSysFileByIds")
    public ActionResult softDeleteSysFileByIds(@RequestParam(name = "id") Long[] ids) {
        sysFileService.softDeleteSysFileByIds(ids);
        return ResultBuilder.buildActionSuccess();
    }

}
